package com.sojson.project.sys.dept.controller;

import java.io.IOException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.sojson.config.exception.TransErrorCode;
import com.sojson.constant.Lock;
import com.sojson.project.sys.dept.controller.param.verify.DeptParamVerify;
import com.sojson.project.sys.dept.entity.dto.DeptDto;
import com.sojson.project.sys.dept.entity.po.Dept;
import com.sojson.project.sys.dept.entity.vo.DeptVo;
import com.sojson.project.sys.dept.service.DeptService;
import com.sojson.project.sys.menu.entity.bo.TreeSelect;
import com.sojson.result.Result;
import com.sojson.util.StringUtil;
import com.sojson.util.lock.CustomLock;
import com.sojson.util.lock.LockUtil;
import com.sojson.util.param.ParamUtil;
import com.sojson.util.token.Token;
import com.sojson.util.token.TokenUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 部门信息表控制器
 * 
 * @author liu
 * @date 2022-11-18
 */
@Api(tags = "部门信息表管理")
@RestController
@RequestMapping("/sys/dept")
public class DeptController {

    @Autowired
    private DeptService deptService;

    /**
     * 单条插入
     * 
     * @param dto
     * @return
     * @throws Exception 
     */
    @PostMapping("/save")
    @PreAuthorize("@ss.hasPermi('/sys/dept/save')")
    @ApiOperation("给部门信息表添加一条数据")
    public Result<Boolean> save(@RequestBody Dept dto) throws Exception {
        dto.insertInit();
        // 校验参数
        Result<Boolean> paramResult = DeptParamVerify.save(dto);
        // 验证不通过
        if (!paramResult.getCode().equals(TransErrorCode.SUCCESS.getCode())) {
            return paramResult;
        }

        CustomLock lock = LockUtil.lock(Lock.DEPT_UPDATE);
        try {
            deptService.add(dto);
        } finally {
            if (lock != null) {
                lock.unlock();
            }
        }

        // 更新缓存用户权限
        Token token = TokenUtil.getToken();
        if (StringUtil.isNotBlankObject(token.getUser()) && !ParamUtil.isAdminSuper(token)) {
            token.setDepts(deptService.listIds(token.getUser()));
            TokenUtil.refreshToken(token);
        }
        return Result.success();
    }

    /**
     * 通过id更新
     * 
     * @param dto
     * @return
     * @throws Exception 
     */
    @PutMapping("/updateById")
    @PreAuthorize("@ss.hasPermi('/sys/dept/updateById')")
    @ApiOperation("通过id更新部门信息表数据")
    public Result<Boolean> updateById(@RequestBody Dept dto) throws Exception {
        dto.updateInit();
        // 校验参数
        Result<Boolean> paramResult = DeptParamVerify.updateById(dto);
        // 验证不通过
        if (!paramResult.getCode().equals(TransErrorCode.SUCCESS.getCode())) {
            return paramResult;
        }

        CustomLock lock = LockUtil.lock(Lock.DEPT_UPDATE);
        try {
            deptService.update(dto);
        } finally {
            if (lock != null) {
                lock.unlock();
            }
        }
        return Result.success();
    }

    /**
     * 列表查询
     * 
     * @param dto
     * @return
     */
    @GetMapping("/list")
    @PreAuthorize("@ss.hasPermi('/sys/dept/list')")
    @ApiOperation(value = "查询部门信息表数据", response = DeptVo.class)
    public Result<List<DeptVo>> list(DeptDto dto) {
        return Result.success(deptService.list(dto));
    }

    /**
     * 通过id查询
     * 
     * @param id
     * @return
     * @throws IOException 
     */
    @GetMapping("/info/{id}")
    @PreAuthorize("@ss.hasPermi('/sys/dept/info/{id}')")
    @ApiOperation(value = "通过id查询部门信息表数据", response = DeptVo.class)
    public Result<DeptVo> info(@PathVariable String id) throws IOException {
        ParamUtil.verifyDept(id);

        return Result.success(deptService.findById(id));
    }

    /**
     * 通过id删除
     * 
     * @param id
     * @return
     * @throws Exception 
     */
    @DeleteMapping("/remove/{id}")
    @PreAuthorize("@ss.hasPermi('/sys/dept/remove/{id}')")
    @ApiOperation("通过id删除部门信息表数据")
    public Result<Boolean> remove(@PathVariable String id) throws Exception {
        ParamUtil.verifyDept(id);

        CustomLock lock = LockUtil.lock(Lock.DEPT_UPDATE);
        try {
            deptService.removeById(id);
        } finally {
            if (lock != null) {
                lock.unlock();
            }
        }

        // 更新缓存用户权限
        Token token = TokenUtil.getToken();
        if (StringUtil.isNotBlankObject(token.getUser()) && !ParamUtil.isAdminSuper(token)) {
            token.setDepts(deptService.listIds(token.getUser()));
            TokenUtil.refreshToken(token);
        }
        return Result.success();
    }

    /**
     * 通过id修改状态
     * 
     * @param dto
     * @return
     * @throws Exception 
     */
    @PutMapping("/changeStatus")
    @PreAuthorize("@ss.hasPermi('/sys/dept/changeStatus')")
    @ApiOperation("通过id修改部门状态")
    public Result<Boolean> changeStatus(@RequestBody Dept dto) throws Exception {
        // 校验参数
        Result<Boolean> paramResult = DeptParamVerify.updateStatus(dto);
        // 验证不通过
        if (!paramResult.getCode().equals(TransErrorCode.SUCCESS.getCode())) {
            return paramResult;
        }

        // 修改状态
        CustomLock lock = LockUtil.lock(Lock.DEPT_UPDATE);
        try {
            Dept dept = new Dept();
            dept.setId(dto.getId());
            dept.setStatus(dto.getStatus());
            deptService.updateStatus(dept);
        } finally {
            if (lock != null) {
                lock.unlock();
            }
        }
        return Result.success();
    }

    /**
     * 获取部门下拉树列表
     * 
     * @param dto
     * @return
     */
    @GetMapping("/treeselect")
    @PreAuthorize("@ss.login()")
    @ApiOperation(value = "获取部门下拉树列表", response = DeptVo.class)
    public Result<List<TreeSelect>> treeselect(DeptDto dto) {
        List<DeptVo> depts = deptService.list(dto);
        return Result.success(deptService.buildDeptTreeSelect(depts));
    }

    /**
     * 加载对应用户部门列表树
     * 
     * @param userId
     * @return
     */
    @GetMapping(value = "/userDeptTreeselect")
    @PreAuthorize("@ss.login()")
    public Result<List<DeptVo>> userDeptTreeselect(DeptDto dto) {
        List<DeptVo> depts = deptService.list(new DeptDto());
        Result<List<DeptVo>> success = Result.success(depts);
        success.put("checkedKeys", deptService.selectDeptListByUserId(dto));
        success.put("depts", deptService.buildDeptTreeSelect(depts));
        return success;
    }

    /**
     * 加载对应角色部门列表树
     * 
     * @param roleId
     * @return
     * @throws IOException 
     */
    @GetMapping(value = "/roleDeptTreeselect/{roleId}")
    @PreAuthorize("@ss.login()")
    public Result<List<DeptVo>> roleDeptTreeselect(@PathVariable("roleId") String roleId) throws IOException {
        if (roleId == null) {
            return Result.success();
        }
        ParamUtil.verifyRoleIdExist(roleId);
        List<DeptVo> depts = deptService.list(new DeptDto());
        Result<List<DeptVo>> success = Result.success(depts);
        success.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
        success.put("depts", deptService.buildDeptTreeSelect(depts));
        return success;
    }

}